package main

import "fmt"

/*
  备忘录模式
  保存一个对象的状态，在需要的时候将其恢复
  该模式在不破坏封装的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态，这样可以在以后将对象恢复到原先保存的状态
  例子
  以游戏中存档
*/


//角色
type Role struct {
	Name string
	Hp int
}

func (r *Role) Save() *MemoryObject {
	m := NewMemoryObject()
	m.Save(r.Name,r.Hp)
	return m
}

func (r *Role) Read(m *MemoryObject)  {
	r.Hp = m.hash[r.Name].(int)
}

func (r *Role) Fight()  {
	r.Hp /= 2
	fmt.Println("hp",r.Hp)
}

func NewRole(name string , hp int) *Role {
	return &Role{Name:name,Hp:hp}
}
//备忘录对象
type MemoryObject struct {
	hash map[string]interface{}
}

func  (m *MemoryObject) Save(key string ,value interface{})  {
	m.hash[key] = value
}

func  (m *MemoryObject) Read(key string) interface{} {
	return  m.hash[key]
}

func NewMemoryObject() *MemoryObject  {
	hash := make(map[string]interface{})
	return &MemoryObject{hash:hash}
}


//存档接口
type Memoriable interface {
	Save() *MemoryObject
	ReadLast()
}

type CaretakerRoleMemory struct {
	archives []*MemoryObject
}


func (c *CaretakerRoleMemory) Save(memory *MemoryObject) {
	c.archives = append(c.archives, memory)
}

func (c *CaretakerRoleMemory) ReadLast() *MemoryObject {
	l := len(c.archives)
	res := c.archives[l-1]
	c.archives = c.archives[:l-1]
	return res
}

func NewCaretakerRoleMemory() *CaretakerRoleMemory {
	caretakerRoleMemory := CaretakerRoleMemory{}
	caretakerRoleMemory.archives = make([]*MemoryObject, 0)
	return &caretakerRoleMemory
}


func main() {
	//存档实例
	s := NewCaretakerRoleMemory()
	//角色A
	a := NewRole("A",100)
	//存档1
	s.Save(a.Save())
	fmt.Println(a)
	//a fight
	a.Fight()
	//存档2
	s.Save(a.Save())
	fmt.Println(a)
	//a fight
	a.Fight()
	//存档3
	s.Save(a.Save())
	fmt.Println(a)
	//a fight
	a.Fight()
	//回档
	a.Read(s.ReadLast())
	fmt.Println(a)
	//回档
	a.Read(s.ReadLast())
	fmt.Println(a)


}
